package com.example.opengldemo._07_texture;

import android.opengl.GLES30;
import android.util.Log;
import android.view.View;

import com.example.opengldemo.util.MatrixState;
import com.example.opengldemo.util.ShaderUtil;
import com.example.opengldemo.util.ShapeFactory;
import java.nio.FloatBuffer;

public class TextureImage {

    int mProgram ;

    int m_A_PositionHandle ;
    int m_A_TexCoorHandle ;
    int m_U_MVPMatrixHandle ;

    String vertexShader = null ; ;
    String fragShader  = null ;

    FloatBuffer vertexBuffer ;
    FloatBuffer texcoorBuffer ;

    int vCount ;

    public TextureImage(View view){
        initShader(view);
        initBufferData() ;
    }

    private void initShader(View view) {
       vertexShader =  ShaderUtil.loadFromAssetsFile("mixing/vertex.sh" ,view.getResources() ) ;
       fragShader = ShaderUtil.loadFromAssetsFile("mixing/fragment.sh" , view.getResources());
       mProgram = ShaderUtil.createProgram(vertexShader  , fragShader);
       initHandle(mProgram);

    }

    private void initHandle(int mProgram) {
        m_A_PositionHandle = GLES30.glGetAttribLocation(mProgram , "aPosition");
        m_A_TexCoorHandle = GLES30.glGetAttribLocation(mProgram , "aTexCoors");
        m_U_MVPMatrixHandle = GLES30.glGetUniformLocation(mProgram , "uMVPMatrix");
    }

    public float UNIT_SIZE = 0.2f ;
    private void initBufferData(){
        float[] vertexArray = new float[]{
                -10*UNIT_SIZE , 10*UNIT_SIZE , 0 ,
                -10*UNIT_SIZE , -10*UNIT_SIZE , 0 ,
                10*UNIT_SIZE , 10*UNIT_SIZE , 0 ,
                10*UNIT_SIZE , -10*UNIT_SIZE , 0
        };
        vertexBuffer = ShapeFactory.getFloatBuffer(vertexArray) ;

        vCount = vertexArray.length /3 ;

        float[] texCoorArray = new float[]{
                0 , 0 ,
                0 , 4f ,
                4f , 0,
                4f , 4f
        };
        texcoorBuffer = ShapeFactory.getFloatBuffer(texCoorArray);

    }

    public void drawSelf(int textureID){

        GLES30.glUseProgram(mProgram);

        GLES30.glVertexAttribPointer(m_A_PositionHandle , 3 , GLES30.GL_FLOAT , false , 3*4 , vertexBuffer);
        GLES30.glVertexAttribPointer(m_A_TexCoorHandle , 2 , GLES30.GL_FLOAT , false , 2*4 , texcoorBuffer);
        GLES30.glUniformMatrix4fv(m_U_MVPMatrixHandle , 1 , false , MatrixState.getFinalMatrix() , 0);
        GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D , textureID);
        GLES30.glEnableVertexAttribArray(m_A_TexCoorHandle);
        GLES30.glEnableVertexAttribArray(m_A_PositionHandle);
        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D,param2State, param3State);
        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D , GLES30.GL_TEXTURE_WRAP_S , paramWarpS);
        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D , GLES30.GL_TEXTURE_WRAP_T , paramWarpT);
        GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP  , 0 , vCount);

        GLES30.glDisableVertexAttribArray(m_A_PositionHandle);
        GLES30.glDisableVertexAttribArray(m_A_TexCoorHandle);
    }
    int param2State = GLES30.GL_TEXTURE_SWIZZLE_R ;
    int param3State = GLES30.GL_RED ;

    int paramWarpS = GLES30.GL_MIRRORED_REPEAT ;
    int paramWarpT = GLES30.GL_MIRRORED_REPEAT ;
    public int update2(){
        Log.e("update2 1" , "param2State >" +param2State) ;
        switch (param2State){
            case GLES30.GL_TEXTURE_SWIZZLE_R :
                param2State = GLES30.GL_TEXTURE_SWIZZLE_G ;
                break ;
            case GLES30.GL_TEXTURE_SWIZZLE_G :
                param2State = GLES30.GL_TEXTURE_SWIZZLE_B ;
                break ;
            case GLES30.GL_TEXTURE_SWIZZLE_B :
                param2State = GLES30.GL_TEXTURE_SWIZZLE_A ;
                break ;
                default:
                    param2State = GLES30.GL_TEXTURE_SWIZZLE_R ;
                    break ;
        }
        Log.e("update2 2" , "param2State >" +param2State) ;
        return param2State ;
    }

    public int update3(){
        Log.e("update3 1" , "param3State >" +param3State) ;
        switch (param3State){
            case GLES30.GL_RED :
                param3State = GLES30.GL_GREEN ;
                break ;
            case GLES30.GL_GREEN :
                param3State = GLES30.GL_BLUE ;
                break ;
            case GLES30.GL_BLUE :
                param3State = GLES30.GL_ALPHA ;
                break ;
            case GLES30.GL_ALPHA :
                param3State = GLES30.GL_ONE ;
                break ;
            case GLES30.GL_ONE :
                param3State = GLES30.GL_ZERO ;
                break ;
            default:
                param3State = GLES30.GL_RED ;
                break ;
        }
        Log.e("update3 1" , "param3State >" +param3State) ;
        return param3State ;
    }

    public int updateWRAPS(){
        Log.e("updateWRAPS 1" , "updateWRAPS >" +paramWarpS) ;
        switch (paramWarpS){
            case GLES30.GL_MIRRORED_REPEAT :
                paramWarpS = GLES30.GL_REPEAT ;
                break ;
            case GLES30.GL_REPEAT :
                paramWarpS = GLES30.GL_CLAMP_TO_EDGE ;
                break ;
            case GLES30.GL_CLAMP_TO_EDGE :
                paramWarpS = GLES30.GL_MIRRORED_REPEAT ;
                break ;
            default:
                paramWarpS = GLES30.GL_MIRRORED_REPEAT ;
                break ;
        }
        Log.e("updateWRAPS 2" , "updateWRAPS >" +paramWarpS) ;
        return paramWarpS ;
    }
    public int updateWRAPT(){
        Log.e("updateWRAPT 1" , "updateWRAPT >" +paramWarpT) ;
        switch (paramWarpT){
            case GLES30.GL_MIRRORED_REPEAT :
                paramWarpT = GLES30.GL_REPEAT ;
                break ;
            case GLES30.GL_REPEAT :
                paramWarpT = GLES30.GL_CLAMP_TO_EDGE ;
                break ;
            case GLES30.GL_CLAMP_TO_EDGE :
                paramWarpT = GLES30.GL_MIRRORED_REPEAT ;
                break ;
            default:
                paramWarpT = GLES30.GL_MIRRORED_REPEAT ;
                break ;
        }
        Log.e("updateWRAPT 2" , "updateWRAPT >" +paramWarpT) ;
        return paramWarpT ;
    }
}


